package com.thesis.manage.common.service.impl;

import com.thesis.manage.common.constant.EmailContent;
import com.thesis.manage.common.email.EmailSendUtil;
import com.thesis.manage.common.entity.ExceptionLog;
import com.thesis.manage.common.mongodb.impl.AbstractMongoServiceImpl;
import com.thesis.manage.common.service.ExceptionLogService;
import com.thesis.manage.common.utils.IpUtil;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author php
 * @date 2018/3/20
 * 异常处理service
 */
public class ExceptionLogServiceImpl extends AbstractMongoServiceImpl<ExceptionLog> implements ExceptionLogService {
    private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
    private static final String SUBJECT = "异常日志";
    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionLogServiceImpl.class);
    private final EmailSendUtil emailSendUtil;

    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired(required = false)
    public ExceptionLogServiceImpl(EmailSendUtil emailSendUtil) {
        this.emailSendUtil = emailSendUtil;
    }

    @Override
    protected Class<ExceptionLog> getEntityClass() {
        return ExceptionLog.class;
    }

    @Override
    public void remoteExceptionHandler(String serverName, String url, String method, String message, List<String> emails) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();
        //异常信息封装
        ExceptionLog exceptionLog = new ExceptionLog();
        exceptionLog.setIp(IpUtil.getIpAddr(request));
        exceptionLog.setServerName(serverName);
        exceptionLog.setUrl(url);
        exceptionLog.setMethod(method);
        exceptionLog.setMessage(message);
        exceptionLog.setCode(response.getStatus());
        this.insert(exceptionLog);
        //记录日志
        LOGGER.error("{},接口发生了如下错误,{}", url, message);
        //发送邮件通知
        if (CollectionUtils.isNotEmpty(emails)) {
            for (String email : emails) {
                this.sendEmail(serverName, exceptionLog, serverName + SUBJECT, email);
            }
        }
    }

    @Override
    public void localExceptionHandler(String message, List<String> emails) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();
        //异常信息封装
        String url = request.getRequestURL().toString();
        ExceptionLog exceptionLog = new ExceptionLog();
        exceptionLog.setIp(IpUtil.getIpAddr(request));
        exceptionLog.setServerName(applicationName);
        exceptionLog.setUrl(url);
        exceptionLog.setMethod(request.getMethod());
        exceptionLog.setMessage(message);
        exceptionLog.setCode(response.getStatus());
        this.insert(exceptionLog);
        //记录日志
        LOGGER.error("{},接口发生了如下错误,{}", url, message);
        //发送邮件通知
        if (CollectionUtils.isNotEmpty(emails)) {
            for (String email : emails) {
                this.sendEmail(applicationName, exceptionLog, applicationName + SUBJECT, email);
            }
        }
    }

    /**
     * 发邮件公用
     *
     * @param serverName   服务名
     * @param exceptionLog 异常消息体
     * @param subject      主题
     * @param email        接受异常邮件
     */
    private void sendEmail(String serverName, ExceptionLog exceptionLog, String subject, String email) {
        if (Pattern.matches(REGEX_EMAIL, email)) {
            //邮件模板
            StringBuilder context = EmailContent.context(email, serverName, exceptionLog);
            this.emailSendUtil.sendHtml(email, subject, context.toString());
        } else {
            LOGGER.error("{},这是邮箱吗", email);
        }
    }
}
